package com.share;

import sun.misc.JavaNioAccess;
import sun.misc.SharedSecrets;
import sun.misc.VM;

import java.nio.ByteBuffer;
import java.util.LinkedList;

/**
 * @author sunxuejian
 * @date 2020/4/24
 *
 *
 * 如果DirectByteBuffer一直被引用，那么DirectByteBuffer（以及其对应的DirectMemory）都不会被gc调，直至oom：direct  buffrer memory
 */
public class MaxDirectMemoryTest3 {

    public static void main(String[] args) throws InterruptedException {

        //-XX:MaxDirectMemorySize=60M  -Xms25m -Xmx25m -XX:+PrintGCDetails
        // -XX:+DisableExplicitGC  有这个则会发生oom，因为不会System.gc()

        byte[] b1 = new byte[1*1024*1024];
        System.out.println(1);
        byte[] b2 = new byte[1*1024*1024];
        System.out.println(2);
        byte[] b3 = new byte[1*1024*1024];
        System.out.println(3);
        byte[] b4 = new byte[1*1024*1024];
        System.out.println(4);

        LinkedList<ByteBuffer> list = new LinkedList<>();
        for(int i =0; i<20; i++) {
            System.out.println("前："  + getNioBufferPool().getTotalCapacity() / 1024.0 / 1024.0);
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(20 * 1024 * 1024);
            list.add(byteBuffer);
            System.out.println("size:" + list.size());
            System.out.println("后：" + getNioBufferPool().getTotalCapacity() / 1024.0 / 1024.0);
            Thread.sleep(5000);
        }

        System.out.println(Runtime.getRuntime().maxMemory() / 1024.0 / 1024.0);
        System.out.println(VM.maxDirectMemory() / 1024.0 / 1024.0);
        System.out.println(getNioBufferPool().getTotalCapacity() / 1024.0 / 1024.0);

        Thread.sleep(Integer.MAX_VALUE);
    }

//        System.out.println(getDirectBufferPoolMBean().getTotalCapacity() / 1024.0 / 1024.0);
//    public static BufferPoolMXBean getDirectBufferPoolMBean(){
//        return ManagementFactory.getPlatformMXBeans(java.lang.management.BufferPoolMXBean.class)
//                .stream()
//                .filter(e -> e.getName().equals("direct"))
//                .findFirst()
//                .orElseThrow();
//    }

    public static JavaNioAccess.BufferPool getNioBufferPool(){
        return SharedSecrets.getJavaNioAccess().getDirectBufferPool();
    }
}



//运行结果：
//E:\jdk\bin\java.exe -XX:MaxDirectMemorySize=60M -Xms25m -Xmx25m -XX:+PrintGCDetails "-javaagent:C:\software\idea\IntelliJ IDEA 2018.2.8\lib\idea_rt.jar=64515:C:\software\idea\IntelliJ IDEA 2018.2.8\bin" -Dfile.encoding=UTF-8 -classpath E:\jdk\jre\lib\charsets.jar;E:\jdk\jre\lib\deploy.jar;E:\jdk\jre\lib\ext\access-bridge-64.jar;E:\jdk\jre\lib\ext\cldrdata.jar;E:\jdk\jre\lib\ext\dnsns.jar;E:\jdk\jre\lib\ext\jaccess.jar;E:\jdk\jre\lib\ext\jfxrt.jar;E:\jdk\jre\lib\ext\localedata.jar;E:\jdk\jre\lib\ext\nashorn.jar;E:\jdk\jre\lib\ext\sunec.jar;E:\jdk\jre\lib\ext\sunjce_provider.jar;E:\jdk\jre\lib\ext\sunmscapi.jar;E:\jdk\jre\lib\ext\sunpkcs11.jar;E:\jdk\jre\lib\ext\zipfs.jar;E:\jdk\jre\lib\javaws.jar;E:\jdk\jre\lib\jce.jar;E:\jdk\jre\lib\jfr.jar;E:\jdk\jre\lib\jfxswt.jar;E:\jdk\jre\lib\jsse.jar;E:\jdk\jre\lib\management-agent.jar;E:\jdk\jre\lib\plugin.jar;E:\jdk\jre\lib\resources.jar;E:\jdk\jre\lib\rt.jar;E:\workspace-sunxj\sunxj-study\sunxj-common\target\classes;E:\maven-repository\io\grpc\grpc-netty\1.1.2\grpc-netty-1.1.2.jar;E:\maven-repository\io\grpc\grpc-core\1.1.2\grpc-core-1.1.2.jar;E:\maven-repository\com\google\errorprone\error_prone_annotations\2.0.11\error_prone_annotations-2.0.11.jar;E:\maven-repository\com\google\code\findbugs\jsr305\3.0.0\jsr305-3.0.0.jar;E:\maven-repository\io\grpc\grpc-context\1.1.2\grpc-context-1.1.2.jar;E:\maven-repository\com\google\instrumentation\instrumentation-api\0.3.0\instrumentation-api-0.3.0.jar;E:\maven-repository\io\netty\netty-codec-http2\4.1.8.Final\netty-codec-http2-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-codec-http\4.1.8.Final\netty-codec-http-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-codec\4.1.8.Final\netty-codec-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-handler\4.1.8.Final\netty-handler-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-buffer\4.1.8.Final\netty-buffer-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-common\4.1.8.Final\netty-common-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-handler-proxy\4.1.8.Final\netty-handler-proxy-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-transport\4.1.8.Final\netty-transport-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-resolver\4.1.8.Final\netty-resolver-4.1.8.Final.jar;E:\maven-repository\io\netty\netty-codec-socks\4.1.8.Final\netty-codec-socks-4.1.8.Final.jar;E:\maven-repository\io\grpc\grpc-protobuf\1.1.2\grpc-protobuf-1.1.2.jar;E:\maven-repository\com\google\protobuf\protobuf-java\3.1.0\protobuf-java-3.1.0.jar;E:\maven-repository\com\google\guava\guava\20.0\guava-20.0.jar;E:\maven-repository\com\google\protobuf\protobuf-java-util\3.1.0\protobuf-java-util-3.1.0.jar;E:\maven-repository\com\google\code\gson\gson\2.7\gson-2.7.jar;E:\maven-repository\io\grpc\grpc-protobuf-lite\1.1.2\grpc-protobuf-lite-1.1.2.jar;E:\maven-repository\io\grpc\grpc-stub\1.1.2\grpc-stub-1.1.2.jar;E:\maven-repository\org\slf4j\slf4j-log4j12\1.6.4\slf4j-log4j12-1.6.4.jar;E:\maven-repository\org\slf4j\slf4j-api\1.6.4\slf4j-api-1.6.4.jar;E:\maven-repository\log4j\log4j\1.2.16\log4j-1.2.16.jar;E:\maven-repository\org\apache\commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar;E:\maven-repository\com\alibaba\fastjson\1.2.60\fastjson-1.2.60.jar;E:\maven-repository\org\springframework\spring-webmvc\4.2.4.RELEASE\spring-webmvc-4.2.4.RELEASE.jar;E:\maven-repository\org\springframework\spring-beans\4.2.4.RELEASE\spring-beans-4.2.4.RELEASE.jar;E:\maven-repository\org\springframework\spring-context\4.2.4.RELEASE\spring-context-4.2.4.RELEASE.jar;E:\maven-repository\org\springframework\spring-aop\4.2.4.RELEASE\spring-aop-4.2.4.RELEASE.jar;E:\maven-repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;E:\maven-repository\org\springframework\spring-core\4.2.4.RELEASE\spring-core-4.2.4.RELEASE.jar;E:\maven-repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;E:\maven-repository\org\springframework\spring-expression\4.2.4.RELEASE\spring-expression-4.2.4.RELEASE.jar;E:\maven-repository\org\springframework\spring-web\4.2.4.RELEASE\spring-web-4.2.4.RELEASE.jar;E:\maven-repository\com\fasterxml\jackson\core\jackson-databind\2.5.4\jackson-databind-2.5.4.jar;E:\maven-repository\com\fasterxml\jackson\core\jackson-annotations\2.5.0\jackson-annotations-2.5.0.jar;E:\maven-repository\com\fasterxml\jackson\core\jackson-core\2.5.4\jackson-core-2.5.4.jar;E:\maven-repository\com\github\dadiyang\equator\1.0.3\equator-1.0.3.jar com.share.MaxDirectMemoryTest2
//        1
//        2
//        3
//        [GC (Allocation Failure) [PSYoungGen: 5742K->1000K(7680K)] 5742K->4080K(25600K), 0.0021971 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
//        4
//        前：0.0
//        size:1
//        后：20.0
//        前：20.0
//        size:2
//        后：40.0
//        前：40.0
//        size:3
//        后：60.0
//        前：60.0
//        [GC (System.gc()) [PSYoungGen: 2152K->936K(7680K)] 5232K->5040K(25600K), 0.0009865 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
//        [Full GC (System.gc()) [PSYoungGen: 936K->0K(7680K)] [ParOldGen: 4104K->4915K(17920K)] 5040K->4915K(25600K), [Metaspace: 3488K->3488K(1056768K)], 0.0051508 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
//        Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
//        at java.nio.Bits.reserveMemory(Bits.java:694)
//        at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
//        at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
//        at com.share.MaxDirectMemoryTest2.main(MaxDirectMemoryTest2.java:35)
//        Heap
//        PSYoungGen      total 7680K, used 394K [0x00000000ff780000, 0x0000000100000000, 0x0000000100000000)
//        eden space 6656K, 5% used [0x00000000ff780000,0x00000000ff7e2b58,0x00000000ffe00000)
//        from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
//        to   space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
//        ParOldGen       total 17920K, used 4915K [0x00000000fe600000, 0x00000000ff780000, 0x00000000ff780000)
//        object space 17920K, 27% used [0x00000000fe600000,0x00000000feaccd08,0x00000000ff780000)
//        Metaspace       used 3518K, capacity 4500K, committed 4864K, reserved 1056768K
//class space    used 381K, capacity 388K, committed 512K, reserved 1048576K
//
//        Process finished with exit code 1